import time

import machine
from machine import Pin

import zz_btn
import zz_code
import zz_match_network
import zz_mqtt
import zz_wifi
import zz_log

log = zz_log.of()
mqtt = zz_mqtt.of()
wifi = zz_wifi.of()


# 重置配网事件
def btn4_click(btn: zz_btn.ZZ_BTN, pin):
    # 启动配网模式
    mqtt.service_close()
    wifi.service_close()
    mk = zz_match_network.of()
    mk.bind_success_callback(mathc_network_callback)
    mk.begin()


pin4 = Pin(4, Pin.IN, Pin.PULL_UP)
btn4 = zz_btn.of(pin4)
btn4.bind_click2(btn4_click)


# 配网成功
def mathc_network_callback(r: zz_code.Return):
    print("配网", r.to_json())
    if r.ok():
        machine.reset()


def connect_wifi():
    mqtt.service_close()

    while True:
        if wifi.service_is(False):
            break

        wifi_ok = wifi.begin_connect()
        if wifi_ok:
            # 从服务器更新设备时间
            zz_wifi.update_machine_time()
            connect_wifi_ok(zz_code.of_return(0, "联网成功"))
            break
        print("联网失败，继续连接")


def connect_wifi_ok(r: zz_code.Return):
    log.debug(f"联网成功: {r.to_json()}")

    mqtt.service_open()
    mqtt.bind_message_callback(mqtt_callback)
    mqtt_ok = mqtt.connect()
    if mqtt_ok:
        # ping电脑是否已开机
        client_ip = zz_code.config_get("client_ip")
        if not zz_code.str_is_empty(client_ip):
            client_state = zz_code.ping(client_ip)  # 开机状态，true:已开机
            rr = zz_code.of_return(0)
            rr.set_data("client_ip", client_ip)
            rr.set_data("client_state", client_state)
            mqtt.send_msg_r(rr, mqtt.topic_push)
        pass
    else:
        mqtt.connect_fail()


# mqtt处理
def mqtt_callback(client: zz_mqtt.ZZ_MQTT, r: zz_code.Return):
    log.debug(f"mqtt_callback: {r.to_json()}")
    if r.err():
        if r.get_errcode() == 5060:
            time.sleep(3)
        return

    action_id = r.get_data("action_id")
    action = r.get_data("action")
    if action == "device_state":
        # 反馈设备状态
        client_ip = zz_code.config_get("client_ip")
        if not zz_code.str_is_empty(client_ip):
            client_state = zz_code.ping(client_ip)  # 开机状态，true:已开机
            rr = zz_code.of_return(0)
            rr.set_data("action", action)
            rr.set_data("action_id", action_id)
            rr.set_data("client_ip", client_ip)
            rr.set_data("client_state", client_state)
            mqtt.send_msg_r(rr)
    else:
        client_ip = zz_code.config_get("client_ip")

        pin_index = r.get_data("pin")
        pin_action = r.get_data("pin_action")
        pin_mode = r.get_data("pin_mode")  # in or out

        rr = zz_code.of_return(0)
        rr.set_data("action_id", action_id)
        rr.set_data("pin", pin_index)

        if not zz_code.str_is_empty(client_ip):
            state = zz_code.ping(client_ip)  # 开机状态，true:已开机
            if state:
                rr.set_errmsg("client_state true")
                client.send_msg_r(rr, mqtt.topic)
                return

        if pin_mode == "in":
            # 输入引脚，反馈电压结果
            pin = Pin(pin_index, Pin.IN)
            rr.set_data("value", pin.value())
        else:
            # 输出操作
            pin = Pin(pin_index, Pin.OUT)
            if pin_action == 2:
                # 点击
                pin.value(1)
                time.sleep_ms(200)
                pin.value(0)
            elif pin_action == 1:
                # 开
                pin.value(1)
            elif pin_action == 0:
                # 关
                pin.value(0)

        client.send_msg_r(rr)


def main():
    wifi.bind_disconnect_callback(connect_wifi)
    connect_wifi()


if __name__ == '__main__':
    main()
    # wifi.bind_disconnect_callback(connect_wifi)
    # connect_wifi()
    # zz_match_network.of().begin()
